/*
 * @Author: soso
 * @Date: 2022-01-12 15:58:23
 * @LastEditTime: 2022-01-25 12:48:20
 * @LastEditors: Please set LastEditors
 * @Description: 文件锁操作
 * @FilePath: /file-sync/utils/flock/flock.go
 */
package utils

import (
	"errors"
	"os"
	"syscall"
)

type Flock struct {
	fileH *os.File
}

// 创建文件锁，配合 defer f.Release() 来使用
func FlockCreate(file *os.File) (f *Flock, e error) {
	return &Flock{
		fileH: file,
	}, nil
}

// 释放文件锁
func (f *Flock) Release() {
	if f != nil && f.fileH != nil {
		f.fileH.Close()
	}
}

// 上锁，配合 defer f.Unlock() 来使用
func (f *Flock) Lock(nb bool) (e error) {
	if f == nil {
		e = errors.New("cannot use lock on a nil flock")
		return
	}
	if nb {
		return syscall.Flock(int(f.fileH.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
	} else {
		return syscall.Flock(int(f.fileH.Fd()), syscall.LOCK_EX)
	}
}

// 解锁
func (f *Flock) Unlock() {
	if f != nil {
		syscall.Flock(int(f.fileH.Fd()), syscall.LOCK_UN)
	}
}
